package sk.tuke.constraintbuilder.editor;

import javax.xml.bind.JAXBException;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.PlatformUI;

import sk.tuke.constraintbuilder.handler.ListRefresh;
import sk.tuke.constraintbuilder.model.Annotations;
import sk.tuke.constraintbuilder.model.Choice;
import sk.tuke.constraintbuilder.model.ConditionsElement;
import sk.tuke.constraintbuilder.model.ConstraintPatterns;
import sk.tuke.constraintbuilder.model.ConstraintPatterns.ConstraintPattern;
import sk.tuke.constraintbuilder.model.ConstraintPatterns.ContentType;
import sk.tuke.constraintbuilder.model.ConstraintPatterns.RuleType;
import sk.tuke.constraintbuilder.model.IElementOfStructuredElement;
import sk.tuke.constraintbuilder.model.Model;
import sk.tuke.constraintbuilder.model.Not;
import sk.tuke.constraintbuilder.model.RuleElement;
import sk.tuke.constraintbuilder.model.SimpleRuleElement;
import sk.tuke.constraintbuilder.model.StructuredRuleElement;
import sk.tuke.constraintbuilder.model.Template;
import sk.tuke.constraintbuilder.model.Value;
import sk.tuke.constraintbuilder.utils.MyUtils;
import sk.tuke.constraintbuilder.views.TemplateEditorView;

public class TemplateEditorController implements IConstraintController {
	
	private Template template;
	private TemplateEditorView view;
	private TemplateEditor editor;
	private ConstraintPatterns constraintPatterns;

	public TemplateEditorController(TemplateEditor editor) {
		this.editor = editor;
		EditorInput editorInput = editor.getEditorInput();
		this.template = (Template) editorInput.getInputElement();
		try {
			constraintPatterns = MyUtils.getConstraintPatterns();
		} catch (JAXBException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	public void setView(TemplateEditorView view){
		this.view = view;
		view.showTemplate(template);
	}

	public void saveTemplate(String name, String description) {
		template.setName(name);
		template.setDescription(description);
		Model.getModel().addTemplate(template);
		Model.getModel().save(template);
		MyUtils.executeCommand(ListRefresh.COMMAND, editor.getSite());
		MessageDialog.openInformation(PlatformUI.getWorkbench().getModalDialogShellProvider().getShell(), "Saved", "Template saved!");
		editor.getParent().refresh(new EditorInput(template));
	}

	public void addRuleElementToRules(String ruleType, String value) {
		RuleElement element = createRuleElement(ruleType, value);
		if(element!=null){
			template.getRule().addElement(element);
			view.addRulePanel(element);
		}
	}
	
	public void addRuleElementToConditions(String ruleType, String value) {
		RuleElement element = createRuleElement(ruleType, value);
		if(element!=null){
			if(template.getCondition()==null){
				template.setCondition(new ConditionsElement());
			}
			template.getCondition().addElement(element);
			view.addCondPanel(element);
		}
	}
	
	private RuleElement createRuleElement(String ruleType, String ruleName){
		ConstraintPattern constraintPattern = constraintPatterns.getPattern(ruleName);
		if(constraintPattern!=null){
			RuleElement ruleElement;
			if(constraintPattern.getRuleType()==RuleType.SIMPLE){
				ruleElement = new SimpleRuleElement();
				ruleElement.setName(ruleName);
				ruleElement.setDescription(constraintPattern.getDescription());
				return ruleElement;
			}
			else if(constraintPattern.getRuleType()==RuleType.STRUCTURED){
				ruleElement = new StructuredRuleElement();
				ruleElement.setName(ruleName);
				ruleElement.setDescription(constraintPattern.getDescription());
				IElementOfStructuredElement subElement = null;
				if(ruleType.equals("NEGATIVE"))subElement = new Not();
				else if(ruleType.equals("CHOICE"))subElement = new Choice();
				if(subElement!=null){
					((StructuredRuleElement)ruleElement).setElement(subElement);
				}
				else if(constraintPattern.getContent()==ContentType.ANNOTATION_CONTAINER){
					((StructuredRuleElement)ruleElement).setElement(new Annotations());
				}	
				else ((StructuredRuleElement)ruleElement).setElement(new Value());
				return ruleElement;
			}
		}
		return null;
	}

	public void removeRuleElement(RuleElement element) {
		template.removeElement(element);
	}


}
